package com.damon.thread;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.damon.entity.ApiEntity;
import com.damon.log.WcsLog;
import com.damon.utils.DbUtil;
import com.damon.utils.GlobalOjbectUtil;
import com.damon.utils.LogUtil;

public class ApiThread extends Thread{
//	Logger logger = LoggerFactory.getLogger(PrintSocketThread.class);
	WcsLog logger;
//	PrintDeviceEntity deviceInfo;
	ApiEntity apiInfo;
	
	public ApiThread(ApiEntity apiEntity) {
		this.apiInfo = apiEntity;
		this.logger = LogUtil.getLogger(ApiThread.class, apiInfo);
	}
	
	@Override
	public void run() {
		String url = apiInfo.getHttpUrl();//调用的api地址
		int time = Integer.valueOf(apiInfo.getHttpInterval());//循环扫描间隔
		String apiName = apiInfo.getHttpUrlDesc();//api描述信息
		String procName = apiInfo.getProcName();//存储过程名称
		String procNameConfirm = apiInfo.getProcNameConfirm();//存储过程名称-获取正确响应后调用
		
		String apiPrintInfo = "["+apiName+"]-["+url+"]";
		logger.info("Api："+apiPrintInfo+"创建线程成功！");
		//打印已连接设备
		GlobalOjbectUtil.getLiveApiThreadSet().add(apiPrintInfo);
		GlobalOjbectUtil.getWindow().getDeviceStatusLabel()
						.setText("已监控Api数："+GlobalOjbectUtil.getLiveApiThreadSet().size());
		while(true) {
			long start = System.currentTimeMillis();
			try {
				ArrayList<String> resultList = getResponeParma(procName);
				//请求参数,没有待回传的任务，param会返回空，不是null
				String param = resultList.get(0);
				String uniqueMsg = resultList.get(1);//参数在表中的唯一标识
				if("".equals(param)==false) {
					logger.info("请求参数：id-"+uniqueMsg+","+param);
					//调用api
					String responesMsg = sendHttpRequest(url, param);
					logger.info("响应信息："+responesMsg);
					
					//根据响应信息判断如何处理该条数据
					updataSortState(procNameConfirm, uniqueMsg,responesMsg);
					logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
				}

			} catch (UnsupportedEncodingException e) {
				logger.error("添加json参数失败", e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			} catch (IOException e) {
				logger.error("发送http请求失败,确认服务端Api接口是否开启！！",e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			} catch (SQLException e) {
				logger.error("调用存储过程(sql)产生的错误",e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			}catch (Exception e) {
				logger.error("未知错误错误："+e.getMessage(),e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			}
//			finally {
//				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
//			}
			//扫描间隔时间时间：1s
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
				logger.error("线程阻塞sleep方法产生错误！",e);
				e.printStackTrace();
			}
		}

	}
	/**
	 * ps:获取响应数据参数
	 * @param procName
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<String> getResponeParma(String procName) throws SQLException {
		//参数：1、api参数 2、唯一标识
		
		String sql = "{call "+procName+"(?,?)}";
		Connection connection = null;
		CallableStatement call = null;
		try {
			connection = DbUtil.getConnection();
			call = connection.prepareCall(sql);
			call.registerOutParameter(1, Types.VARCHAR);
			call.registerOutParameter(2, Types.VARCHAR);
			call.execute();
			ArrayList<String> resultList = new ArrayList<>();
			//如果表里没有任务，数据库会把msg返回空，结果集会取到空字符串，不是null
			String msg = call.getString(1);
			resultList.add(msg);
			String uniqueMsg = call.getString(2);
			resultList.add(uniqueMsg);
			return resultList;
		} finally {
			if(call != null) {
				call.close();
			}
			if(connection != null) {
				connection.close();
			}
		}
	}
	/**
	 * 调用存储过程，更新分拣状态
	 * @param id
	 * @throws SQLException
	 */
	public void updataSortState(String procNameConfirm,String uniqueMsg,String responseMsg) throws SQLException {
		//参数：1、输入参数唯一标识 2、aip响应信息
		String sql = "{call "+procNameConfirm+"(?,?)}";
		Connection connection = null;
		CallableStatement call = null;
		try {
			connection = DbUtil.getConnection();
			call = connection.prepareCall(sql);
			call.setString(1, uniqueMsg);
			call.setString(2, responseMsg);
			call.execute();
//			logger.info("打印状态已更新，数据id："+id);
		} finally {
			if(call != null) {
				call.close();
			}
			if(connection != null) {
				connection.close();
			}
		}
	}
	
	public String sendHttpRequest(String url,String jsonParam) throws ClientProtocolException, IOException {

        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom()
//        		.setConnectTimeout(35000)// 设置连接主机服务超时时间
        		.setConnectTimeout(20000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(20000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        httpPost.addHeader("Content-Type", "application/json");
        // 封装post请求参数
        httpPost.setEntity(new StringEntity(jsonParam)); 
//        try {
//          httpPost.setEntity(new StringEntity(jsonParam)); 
//      } catch (UnsupportedEncodingException e) {
//    	  logger.error("添加json参数失败", e);
//          e.printStackTrace();
//      }
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
//            logger.info("返回为："+result);
        } 
//        catch (IOException e) {
//        	logger.error("发送http请求失败",e);
//            e.printStackTrace();
//        }  
        finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                	logger.error("关闭httpResponse失败",e);
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                	logger.error("关闭httpClient失败",e);
                    e.printStackTrace();
                }
            }
        }
        return result;
    
	}
}
